package com.wwt.file.util;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.wwt.file.enums.FileTypeEnum;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Map;

@Slf4j
public class DocUtil {

    /**
     * 临时生成文件的路径
     */
    private static final String TEMP_FILE_DIR = "tmp\\";

    private static final String LICENSE_FILENAME = "aspose_license.xml";

    /**
     * @param templateFileName 模板文件名称
     * @param fileName      生成的文件名.doc结尾
     * @param dataMap          数据,
     * @description 用模板生成word, 模板存放路径在resources/template下,生成的文件路径在jar包的同级目录/tmp路径下
     * @attention dataMap中的数据不能为null, 可用空值代替
     * @other 导出的doc文件其实是文本文件, 而docx文件是二进制文件(其实是一个压缩包).关于如何导出docx可参考 https://blog.csdn.net/wantLight/article/details/106105416
     **/
    public static void saveWord(String templateFileName, String fileName, Map<String, Object> dataMap) {
        Writer out = null;
        try {
            //根据配置获取FreeMarker模板对象
            Template template = FreeMarkerTemplateFactory.getTemplate(templateFileName);
            String filePath = StrUtil.concat(true,FileUtil.getResourceBasePath(),TEMP_FILE_DIR,fileName);
            //如果文件父目录不存在，则创建父目录
            FileUtil.mkParentDirIfNotExist(filePath);
            // 创建一个Word文档的输出流
            out = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(new File(filePath).toPath()), StandardCharsets.UTF_8));
            template.process(dataMap, out);

            out.flush();
        } catch (Exception e) {
            log.error("saveWord error:{}", e.getMessage(), e);
        } finally {
            IoUtil.close(out);
        }
    }

    /**
     * @param templateFileName 模板文件名称
     * @param fileName         生成的文件名.pdf结尾
     * @param dataMap          数据,
     * @description 用模板先生成生成word, 再转成pdf,模板存放路径在resources/template下,生成的文件路径在jar包的同级目录/tmp路径下
     * @attention dataMap中的数据不能为null, 可用空值代替
     **/
    public static void savePdf(String templateFileName, String fileName, Map<String, Object> dataMap) {
        InputStream docInputStream = null;
        OutputStream outputStream = null;
        try {
            String docFileName = fileName.replace(FileTypeEnum.PDF.getSuffix(), FileTypeEnum.WORD.getSuffix());
            //先生成word
            saveWord(templateFileName, docFileName, dataMap);
            String docFilePath = StrUtil.concat(true,FileUtil.getResourceBasePath(),TEMP_FILE_DIR,docFileName);
            //aspose将word转成pdf
            if (!getLicense()) {
                // 验证License 若不验证则转化出的pdf文档会有水印产生
                return;
            }
            OsInfo osInfo = SystemUtil.getOsInfo();
            //linux环境的字体,需要将c:\windows\fonts下的字体文件放到指定目录下,否则会乱码
            if (osInfo.isLinux()) {
                FontSettings.setFontsFolder("/usr/share/fonts/chinese", true);
            }
            docInputStream = Files.newInputStream(new File(docFilePath).toPath());
            File outputFile = new File(FileUtil.getResourceBasePath(), "tmp/" + fileName);
            outputStream = Files.newOutputStream(outputFile.toPath());
            Document doc = new Document(docInputStream);                    //sourcerFile是将要被转化的word文档
            doc.save(outputStream, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
            //删除生成的临时word文件
            FileUtil.delDir(docFilePath);
        } catch (Exception e) {
            log.error("savePdf error:{}", e.getMessage(), e);
        } finally {
            IoUtil.close(docInputStream);
            IoUtil.close(outputStream);
        }
    }

    /**
     * 判断是否有授权文件 如果没有则会认为是试用版，转换的文件会有水印
     *
     * @return
     */
    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = DocUtil.class.getClassLoader().getResourceAsStream(LICENSE_FILENAME);
            License asposeLic = new License();
            asposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            log.error("getLicense error:{}", e.getMessage());
        }
        return result;
    }

}
